package com.zbkj.service.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.merchant.Merchant;
import com.zbkj.common.model.monitor.ZfbMonitorDeviceBind;
import com.zbkj.common.model.monitor.ZfbMonitorEquipment;
import com.zbkj.common.model.order.Order;
import com.zbkj.common.model.order.OrderDetail;
import com.zbkj.common.model.traceable.ZfbDeviceBatchesItems;
import com.zbkj.common.model.traceable.ZfbDeviceMatchLog;
import com.zbkj.common.model.user.User;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.*;
import com.github.pagehelper.PageHelper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zbkj.common.exception.AppException;

import com.zbkj.common.response.*;
import com.zbkj.common.result.CommonResultCode;
import com.zbkj.common.model.traceable.OrderTraceableRecord;
import com.zbkj.service.dao.OrderTraceableRecordDao;
import com.zbkj.service.service.*;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zbkj.service.service.monitor.IZfbMonitorEquipmentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author dazongzi
* @description OrderTraceableRecordServiceImpl 接口实现
* @date 2025-07-10
*/
@Service
public class OrderTraceableRecordServiceImpl extends ServiceImpl<OrderTraceableRecordDao, OrderTraceableRecord> implements OrderTraceableRecordService {

    @Resource
    private OrderTraceableRecordDao dao;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private UserService userService;
    @Autowired
    private MerchantEmployeeService merchantEmployeeService;
    @Autowired
    private ZfbDeviceBatchesItemsService zfbDeviceBatchesItemsService;
    @Autowired
    private ZfbDeviceMatchLogService zfbDeviceMatchLogService;

    @Autowired
    private ZfbMonitorDeviceBindService zfbMonitorDeviceBindService;

    @Autowired
    private MerchantService merchantService;
    @Autowired
    private IZfbMonitorEquipmentService zfbMonitorEquipmentService;

    @Override
    public Boolean create(OrderTraceableRecordSaveRequest orderTraceableRecordSaveRequest) {
        OrderTraceableRecord orderTraceableRecord = new OrderTraceableRecord();
        BeanUtils.copyProperties(orderTraceableRecordSaveRequest, orderTraceableRecord, "id");
        boolean save = save(orderTraceableRecord);
        if (!save) {
            throw new AppException(CommonResultCode.VALIDATE_FAILED, "添加失败");
        }
        return save;
    }

    /**
     * 分页查询订单溯源记录绑定表
     *
     * @param request          请求参数
     * @param pageParamRequest 分页类参数
     * @return List<OrderTraceableRecord>
     * @author dazongzi
     * @since 2025-07-10
     */
    @Override
    public List<OrderTraceableRecordPageDataResponse> getList(OrderTraceableRecordSearchRequest request, PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        //带 OrderTraceableRecord 类的多条件查询
        LambdaQueryWrapper<OrderTraceableRecord> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.orderByDesc(OrderTraceableRecord::getCreateTime);
        List<OrderTraceableRecord> orderTraceableRecords = dao.selectList(lambdaQueryWrapper);
        // 添加活动状态
        List<OrderTraceableRecordPageDataResponse> orderTraceableRecordResponses = new ArrayList<>();

        orderTraceableRecords.stream().forEach(x->{
            OrderTraceableRecordPageDataResponse orderTraceableRecordResponse = new OrderTraceableRecordPageDataResponse();
            BeanUtils.copyProperties(x, orderTraceableRecordResponse);
            orderTraceableRecordResponses.add(orderTraceableRecordResponse);
        });
        return orderTraceableRecordResponses;
    }

    private OrderTraceableRecord getByIdException(Integer id) {
        OrderTraceableRecord orderTraceableRecord = getById(id);
        if (ObjectUtil.isNull(orderTraceableRecord)) {
            throw new AppException("订单溯源记录绑定表不存在");
        }
        if (orderTraceableRecord.getIsDel()) {
            throw new AppException("订单溯源记录绑定表不存在");
        }
        return orderTraceableRecord;
    }

    /**
    * 批量删除
    * @param idList
    * @return
    */
    @Override
    public boolean batchDelete(List<Integer> idList) {
    LambdaUpdateWrapper<OrderTraceableRecord> luw = Wrappers.lambdaUpdate();
        luw.set(OrderTraceableRecord::getIsDel, true);
        luw.in(OrderTraceableRecord::getId, idList);
        boolean update = update(luw);
        if (!update) {
            throw new AppException(CommonResultCode.ERROR.setMessage("批量删除订单溯源记录绑定表失败"));
        }
        return true;
    }

    /**
    * 查询溯源套餐表详情
    * @param id
    * @return
    */
    @Override
    public OrderTraceableRecordDetailResponse getDetails(Integer id) {
        OrderTraceableRecord orderTraceableRecord = getByIdException(id);
        OrderTraceableRecordDetailResponse response = new OrderTraceableRecordDetailResponse();
        BeanUtils.copyProperties(orderTraceableRecord, response);
        return response;
    }

    @Override
    public boolean receiverBind(OrderReceiverBindRequest request) {
        // 接收器
        LambdaQueryWrapper<ZfbDeviceBatchesItems> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(ZfbDeviceBatchesItems::getDeviceMac, request.getSerialNum().trim());
        checkWrapper.eq(ZfbDeviceBatchesItems::getIsDeleted, 0);
        checkWrapper.last("limit 1");
        ZfbDeviceBatchesItems zfbDeviceBatchesItems = zfbDeviceBatchesItemsService.getOne(checkWrapper);
        if (ObjectUtil.isNull(zfbDeviceBatchesItems)) {
            throw new AppException("设备未在系统备案");
        }
        if (BooleanUtil.isTrue(zfbDeviceBatchesItems.getIsBad())) {
            throw new AppException("设备已损坏无法绑定");
        }
        if (zfbDeviceBatchesItems.getStatus() != 1) {
            throw new AppException("设备状态不支持再次绑定");
        }
        if (zfbDeviceBatchesItems.getUsedStatus() != 0) {
            throw new AppException("设备已消费或损坏");
        }
        // 订单信息
        LambdaQueryWrapper<Order> lqw = Wrappers.lambdaQuery();
        lqw.select(Order::getId, Order::getOrderNo).eq(Order::getIsDel, false).eq(Order::getOrderNo, request.getOrderNo());
        Order order = orderService.getOne(lqw);
        if (ObjectUtil.isNull(order)) {
            throw new AppException("订单不存在");
        }
        // 检查绑定关系
        checkBind(order.getOrderNo(), request);
        // 可以绑定的数量
        checkNum(order.getOrderNo());

        User user = userService.getInfo();
        Date date = new Date();

        OrderTraceableRecord orderTraceableRecord = new OrderTraceableRecord();
        orderTraceableRecord.setOrderNo(order.getOrderNo());
        orderTraceableRecord.setOperatorId(user.getId());
        orderTraceableRecord.setType(1);
        orderTraceableRecord.setSerialNum(request.getSerialNum());
        orderTraceableRecord.setMac(request.getSerialNum());
        orderTraceableRecord.setCreateTime(date);
        boolean save = save(orderTraceableRecord);
        if (!save) {
            throw new AppException(CommonResultCode.ERROR.setMessage("绑定失败"));
        }
        // 写入设备记录
        ZfbDeviceBatchesItems zfbDeviceBatchesItemsUpdate = new ZfbDeviceBatchesItems();
        zfbDeviceBatchesItemsUpdate.setId(zfbDeviceBatchesItems.getId());
        zfbDeviceBatchesItemsUpdate.setOrderNo(order.getOrderNo());
        zfbDeviceBatchesItemsUpdate.setUid(user.getId());
        zfbDeviceBatchesItemsUpdate.setUseTime(date);
        zfbDeviceBatchesItemsUpdate.setUsedStatus(2);
        zfbDeviceBatchesItemsUpdate.setBindTime(date);
        zfbDeviceBatchesItemsService.updateById(zfbDeviceBatchesItemsUpdate);
        return true;
    }

    @Override
    public PageInfo<OrderTraceableRecordListPageResponse> getMerchantAdminPage(OrderTraceableRecordSearchRequest request, PageParamRequest pageParamRequest) {
        Page<OrderTraceableRecord> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        //带 ShortplayItems 类的多条件查询
        LambdaQueryWrapper<OrderTraceableRecord> lambdaQueryWrapper = Wrappers.lambdaQuery();

        if (StrUtil.isNotBlank(request.getOrderNo())) {
            lambdaQueryWrapper.eq(OrderTraceableRecord::getOrderNo, request.getOrderNo().trim());
        }

        lambdaQueryWrapper.eq(OrderTraceableRecord::getIsDel, false);
        lambdaQueryWrapper.orderByDesc(OrderTraceableRecord::getCreateTime);
        List<OrderTraceableRecord> recordList = dao.selectList(lambdaQueryWrapper);
        if (ObjectUtil.isEmpty(recordList)) {
            return CommonPage.copyPageInfo(page, new ArrayList<>());
        }
        // 添加活动状态
        List<OrderTraceableRecordListPageResponse> list = new ArrayList<>();

        recordList.stream().forEach(x->{
            OrderTraceableRecordListPageResponse response = new OrderTraceableRecordListPageResponse();
            BeanUtils.copyProperties(x, response);
            // 操作人
            if (ObjectUtil.isNotNull(x.getOperatorId())) {
                String nickname = userService.getNameById(x.getOperatorId());
                response.setOperator(nickname);
            }
            list.add(response);
        });
        return CommonPage.copyPageInfo(page, list);
    }

    @Override
    public List<OrderTraceableRecord> getListByOrderNo(String orderNo) {
        LambdaQueryWrapper<OrderTraceableRecord> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(OrderTraceableRecord::getOrderNo, orderNo);
        checkWrapper.eq(OrderTraceableRecord::getIsDel, false);
        return list(checkWrapper);
    }

    @Override
    public List<ZfbOrderRecListDataResponse> getOrderRecList(String orderNo, ZfbOrderMonitorLinkDataResponse orderMonitorLink) {
        LambdaQueryWrapper<ZfbMonitorEquipment> lw = new LambdaQueryWrapper<>();
        // 监控名称
        lw.select(ZfbMonitorEquipment::getEquipmentName, ZfbMonitorEquipment::getLicense);
        lw.in(ZfbMonitorEquipment::getLicense, orderMonitorLink.getLicenseList());
        List<ZfbMonitorEquipment> zeList = zfbMonitorEquipmentService.list(lw);
        Map<String, String> nameLMap = zeList.stream()
                .collect(Collectors.toMap(ZfbMonitorEquipment::getLicense, x -> x.getEquipmentName()));

        Map<String, List<String>> licenseList = new HashMap<>();
        for (String license : orderMonitorLink.getLicenseList()) {
            // 获取监控下的接收器
            // 获取绑定关系
            List<ZfbMonitorDeviceBind> bindList = zfbMonitorDeviceBindService.getListInLicense(Arrays.asList(license), -1);
            if (CollUtil.isEmpty(bindList)) {
                continue;
            }
            List<Integer> bindIdList = bindList.stream().map(ZfbMonitorDeviceBind::getId).distinct().collect(Collectors.toList());
            if (CollUtil.isEmpty(bindIdList)) {
                continue;
            }
            // 匹配关系
            List<ZfbDeviceMatchLog> listByBindId = zfbDeviceMatchLogService.getListByBindId(bindIdList);
            if (CollUtil.isEmpty(listByBindId)) {
                continue;
            }
            // 当前可以看的接收器
            List<String> recMacList = listByBindId.stream().map(ZfbDeviceMatchLog::getDeviceMac).distinct().collect(Collectors.toList());
            licenseList.put(license, recMacList);
        }

        LambdaQueryWrapper<OrderTraceableRecord> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(OrderTraceableRecord::getOrderNo, orderNo);
        checkWrapper.eq(OrderTraceableRecord::getIsDel, false);
        List<OrderTraceableRecord> list = list(checkWrapper);
        List<ZfbOrderRecListDataResponse> responseList = new ArrayList<>();
        if (CollUtil.isNotEmpty(list)) {
            for (OrderTraceableRecord orderTraceableRecord : list) {
                ZfbOrderRecListDataResponse response = new ZfbOrderRecListDataResponse();
                BeanUtils.copyProperties(orderTraceableRecord, response);
                // 判断接收器属于哪个监控
                setMonitor(licenseList, response, nameLMap);
                responseList.add(response);
            }
        }
        return responseList;
    }

    @Override
    public boolean receiverUnBind(OrderReceiverUnBindRequest request) {
        OrderTraceableRecord orderTraceableRecord = getById(request.getId());
        if (orderTraceableRecord == null) {
            throw new AppException("查询不到绑定记录");
        }

        orderTraceableRecord.setIsDel(true);
        updateById(orderTraceableRecord);

        LambdaQueryWrapper<ZfbDeviceBatchesItems> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(ZfbDeviceBatchesItems::getDeviceMac, orderTraceableRecord.getSerialNum());
        checkWrapper.eq(ZfbDeviceBatchesItems::getIsDeleted, 0);
        checkWrapper.last("limit 1");
        ZfbDeviceBatchesItems zfbDeviceBatchesItems = zfbDeviceBatchesItemsService.getOne(checkWrapper);
        if (ObjectUtil.isNotNull(zfbDeviceBatchesItems)) {
            zfbDeviceBatchesItems.setOrderNo("");
            zfbDeviceBatchesItems.setBindTime(null);
            zfbDeviceBatchesItems.setUid(0);
            zfbDeviceBatchesItems.setUsedStatus(0);
            zfbDeviceBatchesItems.setUseTime(null);
            zfbDeviceBatchesItems.setStatus(1);
            zfbDeviceBatchesItemsService.updateById(zfbDeviceBatchesItems);
        }
        return true;
    }

    private void setMonitor(Map<String, List<String>> licenseList, ZfbOrderRecListDataResponse response, Map<String, String> nameLMap) {
        for (String licence : licenseList.keySet()) {
            if (licenseList.get(licence).contains(response.getMac())) {
                response.setLinkMonitorLicense(licence);
                response.setLinkMonitorName(nameLMap.get(licence));
            }
        }
    }

    private void checkNum(String order) {
        LambdaQueryWrapper<OrderDetail> lqw =
                Wrappers.lambdaQuery();
        lqw.eq(OrderDetail::getOrderNo, order);
        List<OrderDetail> list = orderDetailService.list(lqw);
        if (CollUtil.isNotEmpty(list)) {
            Integer num = list.stream().mapToInt(OrderDetail::getPayNum).sum();
            // 绑定的数量不能超过订单里面商品购买的数量
            // 绑定数量
            int bindCount = getCountByOrderNo(order);
            if (bindCount + 1 > num) {
                throw new AppException("绑定的设备数量超过了订单购买数量");
            }
        }
    }

    private int getCountByOrderNo(String orderNo) {
        LambdaQueryWrapper<OrderTraceableRecord> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(OrderTraceableRecord::getOrderNo, orderNo);
        checkWrapper.eq(OrderTraceableRecord::getIsDel, false);
        return count(checkWrapper);
    }

    private void checkBind(String orderNo, OrderReceiverBindRequest request) {
        // 检查绑定关系
        LambdaQueryWrapper<OrderTraceableRecord> lqw = Wrappers.lambdaQuery();
        lqw.eq(OrderTraceableRecord::getIsDel, false);
        lqw.eq(OrderTraceableRecord::getOrderNo, orderNo);
        lqw.eq(OrderTraceableRecord::getSerialNum, request.getSerialNum());
        int count = count(lqw);
        if (count > 0) {
            throw new AppException("无需重复绑定");
        }

        lqw = Wrappers.lambdaQuery();
        lqw.eq(OrderTraceableRecord::getIsDel, false);
        lqw.ne(OrderTraceableRecord::getOrderNo, orderNo);
        lqw.eq(OrderTraceableRecord::getSerialNum, request.getSerialNum());
        count = count(lqw);
        if (count > 0) {
            throw new AppException("该接收器已绑定其他订单");
        }
    }

}

